关于反射:如何列出Python模块中的所有函数?

您所在的位置:网站首页 python 如何查看模块所有方法 关于反射:如何列出Python模块中的所有函数?

关于反射:如何列出Python模块中的所有函数?

2023-04-25 06:19| 来源: 网络整理| 查看: 265

我的系统上安装了一个python模块,我想知道其中有哪些函数/类/方法可用。

我想调用每个函数的Doc函数。在Ruby中,我可以做一些类似classname.methods的事情来获取该类上所有可用方法的列表。在python中有类似的东西吗?

比如:

12from somemodule import foo print foo.methods # or whatever is the correct method to call 相关讨论 请考虑审阅所选答案!在其他答案中有更好/更容易使用的解决方案。

您可以使用dir(module)查看所有可用的方法/属性。还可以查看pydocs。

相关讨论 这完全不是真的。dir()函数"试图生成最相关而不是最完整的信息"。来源:docs.python.org/library/functions.html dir。 @引用了杰克代码?然后您将获得字符串模块的可用方法和属性。 @哦,那应该是个问题。是的,你回答了。 是否可以运行EDOCX1[0]以不显示继承的方法? OP明确要求函数,而不是变量。CF使用inspect回答。

一旦你完成了模块的设计,你就可以:

1 help(modulename)

…以交互方式同时获取所有功能的文档。或者你可以使用:

1 dir(modulename)

…只需列出模块中定义的所有函数和变量的名称。

相关讨论 @谢尔约翰……这个批评有什么意义?我的解决方案还列出了函数,而inspect 模块也可以列出变量,尽管这里没有明确要求。此解决方案只需要内置对象,在某些情况下,如果将python安装在受约束/锁定/损坏的环境中,这非常有用。

检查模块。另请参阅pydoc模块、交互式解释器中的help()功能和生成所需文档的pydoc命令行工具。您只需给他们您希望看到的文档的类。例如,它们还可以生成HTML输出并将其写入磁盘。

相关讨论 在我的答案中,我提出了在某些情况下使用ast模块的理由。 我不明白为什么选择这个作为答案,但显然有一个更好的答案… tl;dr of answers below:使用dir返回函数和变量;使用inspect只过滤函数;使用ast不导入进行解析。 正如Sheljohn总结的那样,值得测试每一种方法,因为结果输出在不同的解决方案之间是完全不同的。 这不是一个有帮助的答案,因此我同意那些说不应该选择它作为最佳答案的人。 help()没有显示所有的功能。最好在这个答案中添加一个代码示例。

带inspect的示例:

1234from inspect import getmembers, isfunction from my_project import my_module functions_list = [o for o in getmembers(my_module) if isfunction(o[1])]

getmembers返回(object_name,object_type)元组的列表。

您可以将isfunction替换为inspect模块中的任何其他isxxx函数。

相关讨论 getmembers可以采用谓词,因此您的示例也可以写成:functions_list = [o for o in getmembers(my_module, isfunction)]。 @Christophercurrie,你也可以用functions_list = getmembers(my_module, predicate)避免无用的列表理解,因为它已经返回了一个列表;) 要查找函数是否在该模块中定义(而不是导入的),请添加:t o"if is function(o[1])and o[1],uuu module_uuu==my_module.uu name_uuuuuuuu"--注意,如果导入的函数来自与此模块同名的模块,则不一定会起作用。

12345import types import yourmodule print([getattr(yourmodule, a) for a in dir(yourmodule)   if isinstance(getattr(yourmodule, a), types.FunctionType)]) 相关讨论 对于这条路线,使用getattr(yourmodule,A,none)代替yourmodule。 只显示函数,不显示类等。 您的_u模块。u dict_uuu是我的选择,因为您实际上得到了一个包含函数名:的dict,并且您现在能够动态调用该函数。好时光! python 3对一些糖类很友好:import types def print_module_functions(module):print(''.join([str(module.u dict_uuu.get(a).u name_uuuuuu)for a in dir(module)if isinstance(module.u dict_uuuuuuuuu.get(a),types.functiontype)])

为了完整性起见,我想指出,有时您可能希望解析代码而不是导入代码。import将执行顶级表达式,这可能是一个问题。

例如,我允许用户为使用zippapp制作的包选择入口点函数。使用import和inspect可能会导致代码错误,导致崩溃、帮助消息被打印出来、GUI对话框弹出等等。

相反,我使用ast模块列出所有顶级功能:

12345678910111213141516import ast import sys def top_level_functions(body):     return (f for f in body if isinstance(f, ast.FunctionDef)) def parse_ast(filename):     with open(filename,"rt") as file:         return ast.parse(file.read(), filename=filename) if __name__ =="__main__":     for filename in sys.argv[1:]:         print(filename)         tree = parse_ast(filename)         for func in top_level_functions(tree.body):             print("  %s" % func.name)

将此代码放入list.py中,并将其本身作为输入,我得到:

1234$ python list.py list.py list.py   top_level_functions   parse_ast

当然,导航一个AST有时会很困难,即使对于像Python这样的相对简单的语言,因为AST的级别非常低。但是,如果您有一个简单而清晰的用例,那么它既可行又安全。

不过,缺点是您无法检测运行时生成的函数,如foo = lambda x,y: x*y。

相关讨论 我喜欢这个;我目前正在尝试找出是否有人已经编写了一个类似pydoc的工具,但是没有导入模块。到目前为止,这是我发现的最好的例子:) 这绝对是正确的方法,更安全!谢谢!

这将起到关键作用:

1dir(module)

但是,如果您觉得阅读返回的列表很烦人,只需使用下面的循环来获得每行一个名称。

1for i in dir(module): print i 相关讨论 OP明确要求函数,而不是变量。CF使用inspect回答。另外,这和@danlenski的答案有什么不同?

对于您不希望解析的代码,我建议使用上面的@csl基于ast的方法。

对于其他所有问题,检查模块都是正确的:

12345import inspect import as module functions = inspect.getmembers(module, inspect.isfunction)

这给出了一个形式为[(, ), ...]的2元组列表。

上面的简单答案在各种回答和评论中都有所暗示,但没有明确指出。

相关讨论 谢谢您的拼写;如果您可以在模块上运行import来检查,我认为这是正确的答案。

dir(module)是使用脚本或标准解释器时的标准方式,如大多数答案中所述。

但是,使用类似ipython的交互式python shell,您可以使用tab completion获得模块中定义的所有对象的概述。这比使用脚本和print查看模块中定义的内容要方便得多。

module.将显示模块中定义的所有对象(函数、类等) module.ClassX.将向您显示类的方法和属性 module.function_xy?或module.ClassX.method_xy?将向您显示该函数/方法的docstring module.function_x??或module.SomeClass.method_xy??将向您显示函数/方法的源代码。

对于全局函数,dir()是要使用的命令(正如大多数答案中提到的那样),但是它同时列出了公共函数和非公共函数。

例如运行:

12>>> import re >>> dir(re)

返回如下函数/类:

1'__all__', '_MAXCACHE', '_alphanum_bytes', '_alphanum_str', '_pattern_type', '_pickle', '_subx'

其中一些通常不用于一般编程用途(但模块本身除外,如__doc__、__file__等邓德别名的情况除外)。因此,将它们与公共的列在一起可能没有什么用处(这是Python在使用from module import *时知道要得到什么)。

__all__可以用来解决这个问题,它返回一个模块中所有公共函数和类的列表(那些不以下划线开头的函数和类-_)。见有人能用python解释一下所有的意思吗?用于__all__。

下面是一个例子:

1234>>> import re >>> re.__all__ ['match', 'fullmatch', 'search', 'sub', 'subn', 'split', 'findall', 'finditer', 'compile', 'purge', 'template', 'escape', 'error', 'A', 'I', 'L', 'M', 'S', 'X', 'U', 'ASCII', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL', 'VERBOSE', 'UNICODE'] >>>

所有带有下划线的函数和类都已删除,只剩下那些定义为公共的函数和类,因此可以通过import *使用。

注意,__all__并不总是被定义的。如果不包括,则提出一个AttributeError。

AST模块的情况如下:

123456>>> import ast >>> ast.__all__ Traceback (most recent call last):   File"", line 1, in AttributeError: module 'ast' has no attribute '__all__' >>> 相关讨论 这应该是最重要的答案。

除了前面答案中提到的dir(模块)或help(模块)之外,您还可以尝试:-开放式iPython-导入模块名称-键入module_name,按tab。它将打开一个小窗口,其中列出了Python模块中的所有函数。它看起来很干净。

下面是列出hashlib模块所有函数的代码段

1234567891011121314151617(C:\Program Files\Anaconda2) C:\Users\lenovo>ipython Python 2.7.12 |Anaconda 4.2.0 (64-bit)| (default, Jun 29 2016, 11:07:13) [MSC v.1500 64 bit (AMD64)] Type"copyright","credits" or"license" for more information. IPython 5.1.0 -- An enhanced Interactive Python. ?         -> Introduction and overview of IPython's features. %quickref -> Quick reference. help      -> Python's own help system. object?   -> Details about 'object', use 'object??' for extra details. In [1]: import hashlib In [2]: hashlib.              hashlib.algorithms            hashlib.new                   hashlib.sha256              hashlib.algorithms_available  hashlib.pbkdf2_hmac           hashlib.sha384              hashlib.algorithms_guaranteed hashlib.sha1                  hashlib.sha512              hashlib.md5                   hashlib.sha224

如果您不能在没有导入错误的情况下导入所说的python文件,那么这些答案都不起作用。当我检查一个文件时,情况就是这样的,这个文件来自一个具有很多依赖性的大型代码库。下面将以文本形式处理文件,并搜索以"def"开头的所有方法名,然后打印它们及其行号。

12345import re pattern = re.compile("def (.*)\(") for i, line in enumerate(open('Example.py')):   for match in re.finditer(pattern, line):     print '%s: %s' % (i+1, match.groups()[0]) 相关讨论 在这种情况下,最好使用ast模块。以我的答案为例。 我认为这是一个有效的方法。为什么投反对票?

这将在列表中附加在您的_模块中定义的所有函数。

1234result=[] for i in dir(unit8_conversion_methods):     if type(getattr(your_module, i)).__name__ =="function":         result.append(getattr(your_module, i))

可以使用以下方法从shell中获取模块中的所有函数:

import module

1module.*? 相关讨论 我不知道为什么会投反对票。这对我很管用 @GabrielFair您在哪个版本/平台上运行python?我在py3.7/win10上得到一个语法错误。

使用DIR(模块)不合适(至少不再合适)。代码应如下所示:

1dir('module') or dir('modules')

或者,您可以这样指定您想要的模块:dir('sys')以从模块名sys生成结果。dir()返回错误,而dir('')是您需要的。*帮助("")将返回大多数函数可用的帮助信息。help('modules')将返回模块帮助信息。

感谢所有的投票。当我发布这个时,我使用了python3.2.2和其他3x版本。重点是使用("stufacture")而不是以前的(stufacture)。但我假设你们都坚持使用python2或者使用更新版本的个人电脑,而不是像我一样移动。

http://effbot.org/librarybook/sys.htm网站

相关讨论 或者指定您希望这样的模块:dir("sys")从模块名sys生成结果。dir()返回错误,而dir("")是您需要的。*帮助("")将返回大多数函数可用的帮助信息。帮助("模块")将返回模块帮助信息。 dir("module")返回字符串函数的方法,这与您期望的完全不同。我相信即使对于python 3也是一样的。 dir('anything')返回v3中字符串实例的方法。help确实将字符串解释为所命名的模块。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3